import pyttsx3
import configparser
import pyttsx3
from database_manager import DatabaseManager
from flask import Flask, request, jsonify
import xml.etree.ElementTree as ET

class BroadcastSystem:
    def __init__(self):
        self.config = self._load_config()
        self.tts_engine = pyttsx3.init()
        self._start_config_watcher()
        
        # 初始化数据库管理器
        db_config = {
            'driver': self.config['DATABASE']['driver'],
            'server': self.config['DATABASE']['server'],
            'database': self.config['DATABASE']['database'],
            'username': self.config['DATABASE']['username'],
            'password': self.config['DATABASE']['password']
        }
        self.db_manager = DatabaseManager(db_config)
        
        # 测试用预设文本
        self.test_text = "这是一条测试广播消息，用于验证语音合成效果。"
        
        # 启动Flask服务器
        self.app = Flask(__name__)
        self.app.add_url_rule('/broadcast', 'handle_broadcast', self.handle_broadcast, methods=['POST'])
        
    def __del__(self):
        """析构函数，用于释放TTS引擎资源"""
        if hasattr(self, 'tts_engine'):
            self.tts_engine.stop()
        
    def _start_config_watcher(self):
        """启动配置文件监控"""
        from watchdog.observers import Observer
        from watchdog.events import FileSystemEventHandler
        
        class ConfigChangeHandler(FileSystemEventHandler):
            def on_modified(self, event):
                if event.src_path.endswith('config.ini'):
                    print("检测到config.ini文件修改，重新加载配置...")
                    self.config = self._load_config()
        
        self.observer = Observer()
        self.observer.schedule(ConfigChangeHandler(), path='.', recursive=False)
        self.observer.start()
        
    def _load_config(self):
        """加载配置文件"""
        import os
        config = configparser.ConfigParser()
        config_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'config.ini')
        
        try:
            config.read(config_path)
            
            # 检查必要的配置段
            if 'DATABASE' not in config:
                raise ValueError("配置文件中缺少DATABASE配置段，请检查config.ini文件格式")
                
            return config
        except FileNotFoundError:
            print("未找到配置文件config.ini")
            print("请创建config.ini文件并填写配置")
            exit(1)
        


        
    def process_message(self, message):
        """处理单条新消息并播报"""
        # 根据状态合成不同文本
        if message['prlStatus'] == '播发开始':
            text = f"{message['prlEvnType']}对{message['areaname']}区域发起了{message['prlEvnType']}广播，开始时间为{message['prlStarttime']}，结束时间为{message['prlEndtime']}"
        elif message['prlStatus'] == '播发结束':
            text = f"{message['prlEvnType']}对{message['areaname']}区域{message['prlEvnType']}广播已播发完成，开始时间为{message['prlStarttime']}，结束时间为{message['prlEndtime']}"
        else:
            text = f"广播通知：{message['content']}"
        
        # 语音合成并播放
        try:
            self.tts_engine.say(text)
            self.tts_engine.runAndWait()
        except RuntimeError as e:
            if 'run loop already started' in str(e):
                self.tts_engine.stop()
                self.tts_engine = pyttsx3.init()
                self.tts_engine.say(text)
                self.tts_engine.runAndWait()
        
        # 标记为已处理
        self.db_manager.execute_update(
            "UPDATE BroadcastMessages SET is_processed = 1 WHERE id = ?",
            (message['id'],)
        )
        
    def process_messages(self, messages, combined=False):
        """处理多条消息并播报"""
        if combined:  # 合并播发
            # 按区域分组
            areas = {}
            for msg in messages:
                if msg['areaname'] not in areas:
                    areas[msg['areaname']] = []
                areas[msg['areaname']].append(msg)
            
            # 生成合并播报文本
            text = ""
            for area, msgs in areas.items():
                text += f"{msgs[0]['prlEvnType']}对{area}区域发起了多条广播："
                for msg in msgs:
                    text += f"开始时间{msg['prlStarttime']}至{msg['prlEndtime']}；"
                text += "\n"
        else:  # 单独播发
            for msg in messages:
                self.process_message(msg)
                return
        
        # 语音合成并播放
        try:
            self.tts_engine.say(text)
            self.tts_engine.runAndWait()
        except RuntimeError as e:
            if 'run loop already started' in str(e):
                self.tts_engine.stop()
                self.tts_engine = pyttsx3.init()
                self.tts_engine.say(text)
                self.tts_engine.runAndWait()
        
        # 标记所有消息为已处理
        for msg in messages:
            self.db_manager.execute_update(
                "UPDATE BroadcastMessages SET is_processed = 1 WHERE id = ?",
                (msg['id'],)
            )
        


    def handle_broadcast(self):
        """处理HTTP POST请求"""
        data = request.data
        try:
            xml_data = ET.fromstring(data)
            data = {
                'prlEvnType': xml_data.findtext('prlEvnType'),
                'prlEvnSource': xml_data.findtext('prlEvnSource'),
                'prlAreacode': xml_data.findtext('prlAreacode'),
                'prlStarttime': xml_data.findtext('prlStarttime'),
                'prlEndtime': xml_data.findtext('prlEndtime'),
                'prlStatus': xml_data.findtext('prlStatus'),
                'areaname': xml_data.findtext('areaname')
            }
        except Exception as e:
            return jsonify({'error': 'Invalid XML data'}), 400
            
        # 转换数据格式以匹配现有处理逻辑
        messages = []
        if isinstance(data, list):
            for item in data:
                message = {
                    'prlEvnType': item.get('prlEvnType', ''),
                    'prlEvnSource': item.get('prlEvnSource', ''),
                    'prlAreacode': item.get('prlAreacode', ''),
                    'prlStarttime': item.get('prlStarttime', ''),
                    'prlEndtime': item.get('prlEndtime', ''),
                    'prlStatus': item.get('prlStatus', ''),
                    'areaname': item.get('areaname', item.get('prlAreacode', '')),
                    'content': item.get('content', '')
                }
                messages.append(message)
            self.process_messages(messages)
        else:
            message = {
                'prlEvnType': data.get('prlEvnType', ''),
                'prlEvnSource': data.get('prlEvnSource', ''),
                'prlAreacode': data.get('prlAreacode', ''),
                'prlStarttime': data.get('prlStarttime', ''),
                'prlEndtime': data.get('prlEndtime', ''),
                'prlStatus': data.get('prlStatus', ''),
                'areaname': data.get('areaname', data.get('prlAreacode', '')),
                'content': data.get('content', '')
            }
            self.process_message(message)
            
        return jsonify({'status': 'success'})
        
    def run(self):
        """启动Flask服务器"""
        port = int(self.config['SETTINGS'].get('http_port', 5000))
        self.app.run(host='0.0.0.0', port=port)

if __name__ == "__main__":
    system = BroadcastSystem()
    system.run()